package hedron.editor;

import static hedron.i18n.Internationalization._;
import hedron.Activator;
import hedron.Application;
import hedron.db.model.Stock;
import hedron.db.model.StoreName;
import hedron.db.model.StoredStock;
import hedron.dialog.ColumnDialog;
import hedron.dialog.GroupStockDialog;
import hedron.dialog.MoveSplitStockDialog;
import hedron.dialog.StoredStockDialog;
import hedron.dialog.StringDialog;
import hedron.editorinput.DummyEditorInput;
import hedron.ui.UIFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.part.EditorPart;

public class StoreEditor extends EditorPart {
	public static final String ID = "HEDRON.StoreEditor";

	private FormToolkit toolkit;
	private ScrolledForm form;

	ArrayList<StoreName> storeNames;

	Text filterField;
	Combo storesCombo;

	StoreName currentStore;
	Table stocksTable;

	Listener sortListener;
	int currentSorting = 0;
	int previousSorting = 0;
	boolean summarizeResult = false;

	String[] sortColumns = { "GROUP_NAME", "STOCK_NAME", "QTY", "METRIC", "PRICE_BUY", "PRICE_SELL", "DELIVERY_DATE",
			"C_NAME" };

	String[] columnNames = { _("Column.Group"), _("Column.Stock"), _("Column.Quantity"), _("Column.Metric"),
			_("Column.BuyPrice"), _("Column.SellPrice"), _("Column.StoredDate"), _("Column.Deliverer") };

	protected void initTableItem(TableItem item, StoredStock storedStock) {
		int i = 0;
		item.setData(storedStock);
		item.setText(i++, storedStock.GROUP_NAME);
		item.setText(i++, storedStock.STOCK_NAME);
		item.setText(i++, String.valueOf(storedStock.QTY));
		item.setText(i++, storedStock.METRIC);
		item.setText(i++, EditorUtils.formatDouble(storedStock.PRICE_BUY));
		item.setText(i++, EditorUtils.formatDouble(storedStock.PRICE_SELL));
		item.setText(i++, Application.formatDate(storedStock.DELIVERY_DATE));
		item.setText(i++, storedStock.C_NAME);
	}

	public void refresh() {
		{
			storeNames = Application.STORES.getStoreNames();
			String[] names = new String[storeNames.size()];
			int i = 0;
			for (StoreName storeName : storeNames) {
				names[i++] = storeName.STORE_NAME;
			}
			int selection = storesCombo.getSelectionIndex();
			storesCombo.setItems(names);
			storesCombo.select(selection);
		}

		List<StoredStock> storedStocks = Application.STORES.getStoredStocks(currentStore, filterField.getText(),
				sortColumns[currentSorting], previousSorting == currentSorting ? "ASC" : "DESC", summarizeResult);

		stocksTable.setRedraw(false);
		stocksTable.removeAll();
		for (StoredStock storedStock : storedStocks) {
			TableItem item = new TableItem(stocksTable, SWT.NONE);
			initTableItem(item, storedStock);
		}
		for (int i = 0; i < columnNames.length; i++) {
			stocksTable.getColumn(i).pack();
		}
		stocksTable.setRedraw(true);
	}

	private void addStoredStock() {
		StoredStockDialog dialog = new StoredStockDialog(Application.getActiveWorkbench().getShell(), this,
				currentStore);
		dialog.open();
		refresh();
	}

	private void moveStoredStock() {
		int selection = stocksTable.getSelectionIndex();
		if (selection >= 0) {
			StoredStock selectedStock = (StoredStock) stocksTable.getItem(selection).getData();
			MoveSplitStockDialog dialog = new MoveSplitStockDialog(Application.getActiveWorkbench().getShell(),
					selectedStock, currentStore);
			dialog.open();
			refresh();
		} else {
			Application.setStatusMessage(1, _("Editor.Store.Warn.Move.Stock"));
		}
	}

	private void groupStoredStock() {
		final int currentStore = storesCombo.getSelectionIndex();
		if (currentStore > -1) {
			final StoreName storeName = storeNames.get(currentStore);
			ArrayList<Stock> availableGroupings = Application.STOCKS.getAvailableGroupings(storeName);
			if (availableGroupings.size() > 0) {
				GroupStockDialog dialog = new GroupStockDialog(Application.getActiveWorkbench().getShell(), storeName);
				dialog.open();
				refresh();
			} else {
				Application.setStatusMessage(1, _("Editor.Store.Warn.Group.Stock"));
			}
		}
	}

	private void destoreStock() {
		int selection = stocksTable.getSelectionIndex();
		if (selection >= 0) {
			StoredStock selectedStock = (StoredStock) stocksTable.getItem(selection).getData();
			StringDialog dialog = new StringDialog(Application.getActiveWorkbench().getShell(),
					_("Editor.Store.Destore.Reason"), "");

			while (dialog.open() == Window.OK) {
				final String reason = dialog.getString().trim();
				if (reason.length() > 0) {
					Application.STORES.destoreStock(selectedStock, reason);
					break;
				}
			}
			refresh();
		} else {
			Application.setStatusMessage(1, _("Editor.Store.Warn.Destore.Stock"));
		}
	}

	@Override
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		setSite(site);
		setInput(input);
		setTitleImage(Activator.getImage("icons/store.png"));

		sortListener = new Listener() {
			public void handleEvent(Event e) {
				if (e.widget instanceof TableColumn) {
					int sortColumn = 0;
					for (; sortColumn < columnNames.length; sortColumn++) {
						if (columnNames[sortColumn].equals(((TableColumn) e.widget).getText())) {
							break;
						}
					}
					currentSorting = sortColumn;
					stocksTable.setSortColumn((TableColumn) e.widget);
					if (previousSorting != currentSorting) {
						stocksTable.setSortDirection(SWT.UP);
						previousSorting = currentSorting;
					} else {
						stocksTable.setSortDirection(SWT.DOWN);
						previousSorting = -1;
					}
					refresh();
				}
			}
		};
	}

	public void dispose() {
		toolkit.dispose();
		super.dispose();
	}

	@Override
	public void setFocus() {}

	private static final String layout = "<layout columns=\"2\" align=\"FILL\" valign=\"FILL\">"
			+ "<section text=\"Editor.Store.Section.Store\" align=\"BEGINING\" valign=\"BEGINING\">"
			+ "     <combo id=\"storesCombo\" width=\"170\" readonly=\"true\" align=\"FILL\" valign=\"BEGINING\"/>"
			+ "</section>"
			+ "<section text=\"Editor.Store.Section.Search\" columns=\"3\" align=\"FILL\" valign=\"BEGINING\">"
			+ "     <label text=\"Editor.Store.Label.Search\" align=\"BEGINING\" valign=\"CENTER\"/>"
			+ "      <text  id=\"filterField\" align=\"FILL\" valign=\"CENTER\"/>"
			+ "      <button id=\"searchButton\" text=\"Editor.Store.Button.Search\" icon=\"icons/search.png\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"CENTER\"/>"
			+ "</section>"
			+ "<section text=\"Editor.Store.Section.Stocks\" colspan=\"2\" columns=\"2\" align=\"FILL\" valign=\"FILL\">"
			+ "     <table id=\"stocksTable\" fullselection=\"true\" align=\"FILL\" valign=\"FILL\"/>"
			+ "     <container align=\"BEGINING\" valign=\"FILL\">"
			+ "         <button id=\"addButton\" text=\"Editor.Store.Button.Add\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "         <button id=\"moveButton\" text=\"Editor.Store.Button.Move\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "         <button id=\"groupButton\" text=\"Editor.Store.Button.Grouping\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "     	<label text=\"\" height=\"20\" align=\"BEGINING\" valign=\"BEGINING\"/>"
			+ "         <button id=\"destoreButton\" text=\"Editor.Store.Button.Destore\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "     </container>"
			+ "     <button id=\"summarizeButton\" text=\"Editor.Store.Button.Summarize\" check=\"true\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "</section>"
			+ "</layout>";
	
	@Override
	public void createPartControl(Composite parent) {
		toolkit = new FormToolkit(parent.getDisplay());
		form = toolkit.createScrolledForm(parent);

		form.setText(_("Editor.Store.Title"));
		form.setBackgroundImage(Activator.getImage("icons/form_background.png"));

		// createPartControl1(parent);
		Map<String, Control> components = UIFactory.createUI(form.getBody(), layout, toolkit);
		storesCombo = (Combo) components.get("storesCombo");
		filterField = (Text) components.get("filterField");
		Button searchButton = (Button) components.get("searchButton");
		stocksTable = (Table) components.get("stocksTable");
		Button addButton = (Button) components.get("addButton");
		final Button moveButton = (Button) components.get("moveButton");
		Button groupButton = (Button) components.get("groupButton");
		final Button destoreButton = (Button) components.get("destoreButton");
		Button summarizeButton = (Button) components.get("summarizeButton");

		{
			storeNames = Application.STORES.getStoreNames();
			String[] names = new String[storeNames.size()];
			int i = 0;
			for (StoreName storeName : storeNames) {
				names[i++] = storeName.STORE_NAME;
			}
			storesCombo.setItems(names);
			storesCombo.select(0);
			currentStore = storeNames.get(0);

			storesCombo.addSelectionListener(new SelectionListener() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					currentStore = storeNames.get(storesCombo.getSelectionIndex());
					refresh();
				}

				@Override
				public void widgetDefaultSelected(SelectionEvent e) {}
			});
		}
		{
			filterField.addKeyListener(new KeyListener() {
				@Override
				public void keyReleased(KeyEvent e) {
					if (e.keyCode == 13) {
						refresh();
					}
				}
				@Override
				public void keyPressed(KeyEvent e) {}
			});
		}

		searchButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				refresh();
			}
		});

		{
			for (String columnName : columnNames) {
				TableColumn column = new TableColumn(stocksTable, SWT.NONE);
				column.setText(columnName);
				column.addListener(SWT.Selection, sortListener);
			}

			stocksTable.setHeaderVisible(true);
			stocksTable.setLinesVisible(true);

			stocksTable.setSortColumn(stocksTable.getColumn(0));
			stocksTable.setSortDirection(SWT.UP);
		}

		addButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				addStoredStock();
			}
		});

		moveButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				moveStoredStock();
			}
		});

		groupButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				groupStoredStock();
			}
		});

		destoreButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				destoreStock();
			}
		});

		summarizeButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				summarizeResult = ((Button) e.widget).getSelection();
				moveButton.setEnabled(!summarizeResult);
				destoreButton.setEnabled(!summarizeResult);
				refresh();
			}
		});

		// tool-bar buttons
		{
			Action action = new Action("add", Action.AS_PUSH_BUTTON) { //$NON-NLS-1$
				public void run() {
					addStoredStock();
				}
			};
			action.setToolTipText(_("Editor.Store.Tooltip.Add"));
			action.setImageDescriptor(Activator.getImageDescriptor("icons/add.png"));
			form.getToolBarManager().add(action);
		}
		{
			Action action = new Action("print", Action.AS_PUSH_BUTTON) { //$NON-NLS-1$
				public void run() {
					IWorkbenchPage page = getSite().getPage();
					try {
						ColumnDialog dialog = new ColumnDialog(Application.getActiveWorkbench().getShell(), stocksTable);

						if (dialog.open() == Window.OK) {
							final boolean[] selectedColums = dialog.selectedColums;
							final TableColumn[] columns = stocksTable.getColumns();
							final StringBuilder html = new StringBuilder();

							html.append("<HTML><head><STYLE type=\"text/css\"> "
									+ "body{ background-color: #FFFF; color: #606060; font-size: 13px; font-family: tahoma, verdana, arial, sans-serif; margin: 0; padding: 0; height: 100%; } "
									+ "table { background-color: #FFFFFF; font-size: 11px; }</STYLE></head><BODY>");
							html.append("<table border=1 width='100%' cellspacing=0 cellpadding=1 style='border: #ccc solid 1px;'>");
							html.append("<tr>");
							for (int i = 0; i < selectedColums.length; i++) {
								if (selectedColums[i]) {
									html.append("<td nowrap=true><b>");
									html.append(columns[i].getText());
									html.append("</b></td>");
								}
							}
							html.append("</tr>");
							for (int j = 0; j < stocksTable.getItemCount(); j++) {

								html.append("<tr>");
								for (int i = 0; i < selectedColums.length; i++) {
									if (selectedColums[i]) {
										html.append("<td>");
										html.append(stocksTable.getItem(j).getText(i));
										html.append("&nbsp;</td>");
									}
								}
								html.append("</tr>");
							}
							html.append("</table></BODY></HTML>");

							String name = _("Dialog.StoredStock.Print");
							DummyEditorInput editorInput = new DummyEditorInput(Application.ID.getUID(), name);
							editorInput.setData(html);
							page.openEditor(editorInput, HTMLPrintEditor.ID);
						}
					} catch (PartInitException e) {
						Application.log.log(Level.OFF, "", e);
					}
				}
			};
			action.setToolTipText(_("Editor.Store.Tooltip.Print"));
			action.setImageDescriptor(Activator.getImageDescriptor("icons/print.png"));
			form.getToolBarManager().add(action);
		}
		{
			Action action = new Action("refresh", Action.AS_PUSH_BUTTON) { //$NON-NLS-1$
				public void run() {
					refresh();
				}
			};
			action.setToolTipText(_("Editor.Store.Tooltip.Refresh"));
			action.setImageDescriptor(Activator.getImageDescriptor("icons/refresh.png"));
			form.getToolBarManager().add(action);
		}
		form.updateToolBar();
		refresh();
	}

	@Override
	public boolean isDirty() {
		return false;
	}

	@Override
	public boolean isSaveAsAllowed() {
		return false;
	}

	@Override
	public void doSave(IProgressMonitor monitor) {}

	@Override
	public void doSaveAs() {}

}
